package com.newtype.meeting.client.mvc.frontend;

import java.util.Date;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.newtype.meeting.client.AppEvents;
import com.newtype.meeting.client.GMeeting;
import com.newtype.meeting.client.model.Account;
import com.newtype.meeting.client.model.MeetingCategory;
import com.newtype.meeting.client.model.MeetingRecord;
import com.newtype.meeting.client.model.MeetingReport;
import com.newtype.meeting.client.model.MeetingStart;
import com.newtype.meeting.client.service.AccountServiceAsync;
import com.newtype.meeting.client.service.DepartmentServiceAsync;
import com.newtype.meeting.client.service.MeetingCategoryServiceAsync;
import com.newtype.meeting.client.service.MeetingServiceAsync;
import com.newtype.meeting.client.service.MeetingStartServiceAsync;
import com.newtype.meeting.shared.AccountSummaryDTO;
import com.newtype.meeting.shared.DepartmentTreeDTO;

public class StartMeetingController extends Controller{
	private StartMeetingView startMeetingView;
	private MeetingStartServiceAsync startService;
	private MeetingServiceAsync meetingService;
	private DepartmentServiceAsync departmentService;
	private AccountServiceAsync accountService;
	private MeetingCategoryServiceAsync categoryService;
	private Account account;

	public StartMeetingController() {
		registerEventTypes(AppEvents.ViewStartMeeting);
		registerEventTypes(AppEvents.MeetingScratchtape);
		registerEventTypes(AppEvents.ToReportWindow);
		registerEventTypes(AppEvents.ToRecordWindow);
		registerEventTypes(AppEvents.SaveorUpdateMeetingReport);
		registerEventTypes(AppEvents.SaveorUpdateMeetingRecord);
		registerEventTypes(AppEvents.ToOrganizationWindow);
		registerEventTypes(AppEvents.ToPersonnelSingleWindow);
		registerEventTypes(AppEvents.ToOrganizationSeperateWindow);
		registerEventTypes(AppEvents.ToStartMeeting);
		registerEventTypes(AppEvents.DeleteDraft);
	}

	@Override
	protected void initialize() {
		super.initialize();
		startMeetingView = new StartMeetingView(this);
		startService = Registry.get(GMeeting.MEETINGSTART_SERVICE);
		meetingService = Registry.get(GMeeting.MEETING_SERVICE);
		departmentService = Registry.get(GMeeting.DEPARTMENT_SERVICE);
		accountService = Registry.get(GMeeting.ACCOUNT_SERVICE);
		categoryService = Registry.get(GMeeting.CATEGORY_SERVICE);

		account = Registry.get(GMeeting.ACCOUNT);
	}

	@Override
	public void handleEvent(AppEvent event) {
		EventType type = event.getType();
		if (type == AppEvents.ViewStartMeeting) {
			onViewStartMeeting(event);
		} else if (type == AppEvents.MeetingScratchtape) {
			onMeetingScratchtape(event);
		} else if (type == AppEvents.ToReportWindow) {
			onToReportWindow(event);
		} else if (type == AppEvents.SaveorUpdateMeetingReport) {
			onSaveorUpdateReport(event);
		} else if (type == AppEvents.SaveorUpdateMeetingRecord) {
			onSaveorUpdateRecord(event);
		} else if (type == AppEvents.ToRecordWindow) {
			onToRecordWindow(event);
		} else if (type == AppEvents.ToOrganizationWindow) {
			onToOrganizationWindow(event);
		} else if (type == AppEvents.ToPersonnelSingleWindow) {
			onToPersonnelSingleWindow(event);
		} else if (type == AppEvents.ToStartMeeting) {
			onToStartMeeting(event);
		} else if (type == AppEvents.DeleteDraft) {
			onDeleteDraft(event);
		} else if (type == AppEvents.ToOrganizationSeperateWindow) {
			onToOrganizationSeperateWindow(event);
		}
	}

	/**
	 * 弹出组织/人员分开选取窗口
	 * @param event
	 */
	private void onToOrganizationSeperateWindow(AppEvent event) {
		final AppEvent ae = new AppEvent(event.getType());
		ae.setData("organization", event.getData());
		departmentService.getTreeModel(new AsyncCallback<DepartmentTreeDTO>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(DepartmentTreeDTO result) {
				ae.setData("model", result);
				forwardToView(startMeetingView, ae);
			}
		});
	}

	/**
	 * 跳转至选取人员窗口
	 * @param event
	 */
	private void onToPersonnelSingleWindow(final AppEvent event) {
		departmentService.getTreeModel(new AsyncCallback<DepartmentTreeDTO>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(DepartmentTreeDTO result) {
				final AppEvent ae = new AppEvent(event.getType());
				ae.setData("model", result);
				forwardToView(startMeetingView, ae);
			}
		});
	}

	/**
	 * 执行跳转到选取组织人员窗口
	 * @param event
	 */
	private void onToOrganizationWindow(final AppEvent event) {
		final AppEvent ae = new AppEvent(event.getType());
		ae.setData("personnel", event.getData());
		departmentService.getTreeModel(new AsyncCallback<DepartmentTreeDTO>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(DepartmentTreeDTO result) {
				ae.setData("model", result);
				forwardToView(startMeetingView, ae);
			}
		});
	}

	/**
	 * 保存或更新会议记录
	 * @param event
	 */
	private void onSaveorUpdateRecord(AppEvent event) {
		final MeetingRecord record = event.getData();
		record.setDeptID(account.getDeptID());
		record.setAccountID(account.getAccountID());
		record.setFullName(account.getFullName());
		record.setSubmitDATE(new Date());
		meetingService.saveMeetingRecord(record, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(Void result) {
				MessageBox.alert("提示信息", "送出成功", null);
				Dispatcher.forwardEvent(AppEvents.ViewMeeting);
			}
		});
	}

	/**
	 * 保存或更新会议报告
	 * @param event
	 */
	private void onSaveorUpdateReport(AppEvent event) {
		final MeetingReport report = event.getData();
		report.setAccountID(account.getAccountID());
		report.setDeptID(account.getDeptID());
		report.setFullName(account.getFullName());
		report.setSubmitDate(new Date());
		meetingService.saveMeetingReport(report, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(Void result) {
				MessageBox.alert("提示信息", "送出成功", null);
				Dispatcher.forwardEvent(AppEvents.ViewMeeting);
			}
		});
	}

	/**
	 * 弹出登录报告窗口
	 * @param event
	 */
	private void onToReportWindow(AppEvent event) {
		AppEvent ae = new AppEvent(event.getType());
		ae.setData("report", (MeetingReport) event.getData());
		forwardToView(startMeetingView, ae);
	}

	/**
	 * 弹出会议报告窗口
	 * @param event
	 */
	private void onToRecordWindow(AppEvent event) {
		AppEvent ae = new AppEvent(event.getType());
		ae.setData("record", (MeetingRecord) event.getData());
		forwardToView(startMeetingView, ae);
	}

	/**
	 * 暂存草稿
	 * @param event
	 */
	private void onMeetingScratchtape(AppEvent event) {
		final MeetingStart start = event.getData();
		start.setDraftTAG(1);//草稿标签
		start.setNotifierID(account.getAccountID());
		start.setSubmitDate(new Date());
		startService.saveMeetingStart(start, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(Void result) {
				MessageBox.alert("提示信息", "暂存草稿成功", null);
				Dispatcher.forwardEvent(AppEvents.ViewMeeting);
			}
		});
	}

	/**
	 * 发起新会议
	 * @param event
	 */
	private void onViewStartMeeting(AppEvent event) {
		final AppEvent ae = new AppEvent(event.getType());
		accountService.getAccountSummaryDTO(account.getId(),
				new AsyncCallback<AccountSummaryDTO>() {
					@Override
					public void onFailure(Throwable caught) {
						Dispatcher.forwardEvent(AppEvents.Error, caught);
					}

					@Override
					public void onSuccess(AccountSummaryDTO result) {
						ae.setData("account", result);
						//获取会议类别集合
						categoryService
								.listAllChildren(new AsyncCallback<List<MeetingCategory>>() {
									@Override
									public void onFailure(Throwable caught) {
										Dispatcher.forwardEvent(
												AppEvents.Error, caught);
									}

									@Override
									public void onSuccess(
											List<MeetingCategory> result) {
										ae.setData("cates", result);
										forwardToView(startMeetingView, ae);
									}
								});
					}
				});
	}

	/** 跳转至发起会议窗口 */
	private void onToStartMeeting(final AppEvent event) {
		//接收参数
		final AppEvent ae = new AppEvent(event.getType());
		final MeetingStart start = event.getData();
		ae.setData("start", start);
		//获取所有下级会议类别
		categoryService
				.listAllChildren(new AsyncCallback<List<MeetingCategory>>() {
					@Override
					public void onFailure(Throwable caught) {
						Dispatcher.forwardEvent(AppEvents.Error, caught);
					}

					@Override
					public void onSuccess(List<MeetingCategory> result) {
						ae.setData("cates", result);
						if (start.getCategoryID() != null) {
							//获取当前所选择会议类别对象
							categoryService.getCategory(start.getCategoryID(),
									new AsyncCallback<MeetingCategory>() {
										@Override
										public void onFailure(Throwable caught) {
											Dispatcher.forwardEvent(
													AppEvents.Error, caught);
										}

										@Override
										public void onSuccess(
												MeetingCategory result) {
											MeetingCategory currentCate = new MeetingCategory(
													result.getId(), result
															.getCategoryName());
											ae.setData("currentCate",
													currentCate);
											forwardToView(startMeetingView, ae);
										}
									});
						} else {
							forwardToView(startMeetingView, ae);
						}
					}
				});
	}

	/**
	 * 执行删除草稿操作
	 * @param event
	 */
	private void onDeleteDraft(AppEvent event) {
		//接收参数
		String id = event.getData();
		startService.deleteMeetingStart(id, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				Dispatcher.forwardEvent(AppEvents.Error, caught);
			}

			@Override
			public void onSuccess(Void result) {
				MessageBox.alert("提示信息", "删除草稿成功", null);
				Dispatcher.forwardEvent(AppEvents.ViewMeeting);
			}
		});
	}

}
